"""
证书上传 API
用于上传已申请的证书和私钥
"""
from fastapi import APIRouter, Depends, Request
from motor.motor_asyncio import AsyncIOMotorDatabase
from pydantic import BaseModel, Field
from bson import ObjectId
from datetime import datetime
from typing import Optional

from database.connection import get_database
from models.certificate import CertificateStatus
from api.deps_v1 import get_current_user
from utils.response import success, error
from models.response import ErrorCode
from utils.crypto import crypto_service
from services.audit import log_audit
from models.audit import AuditAction, AuditStatus, ResourceType

router = APIRouter(prefix="/sac/v1/certificates", tags=["证书服务"])

# 服务名称
SERVICE_NAME = "certificates"


# ========== 请求模型 ==========

class UploadCertificateRequest(BaseModel):
    """上传证书请求"""
    certificate_id: str = Field(..., description="证书 ID")
    cert_fullchain_pem: str = Field(..., description="完整证书链 PEM 格式")
    private_key_pem: str = Field(..., description="私钥 PEM 格式")
    expires_at: datetime = Field(..., description="证书过期时间")


class UploadCertificateResult(BaseModel):
    """上传证书结果"""
    certificate_id: str
    status: str
    message: str


# ========== API 接口 ==========

@router.post("/UploadCertificate", summary="上传证书")
async def upload_certificate(
    request: Request,
    body: UploadCertificateRequest,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_database)
):
    """
    上传已申请的证书和私钥
    
    用于手动申请证书后，将证书内容上传到系统
    """
    try:
        request_id = request.state.request_id
        
        if not ObjectId.is_valid(body.certificate_id):
            return error(
                request, "UploadCertificate", SERVICE_NAME,
                ErrorCode.INVALID_PARAMETER,
                detail="无效的证书 ID"
            )
        
        # 查询证书
        cert = await db.certificates.find_one({
            "_id": ObjectId(body.certificate_id),
            "user_id": current_user["id"],
            "deleted_at": None
        })
        
        if not cert:
            return error(
                request, "UploadCertificate", SERVICE_NAME,
                ErrorCode.CERT_NOT_FOUND
            )
        
        # 验证证书内容格式
        if "BEGIN CERTIFICATE" not in body.cert_fullchain_pem:
            return error(
                request, "UploadCertificate", SERVICE_NAME,
                ErrorCode.INVALID_PARAMETER,
                detail="证书格式无效，需要 PEM 格式"
            )
        
        if "BEGIN" not in body.private_key_pem or "PRIVATE KEY" not in body.private_key_pem:
            return error(
                request, "UploadCertificate", SERVICE_NAME,
                ErrorCode.INVALID_PARAMETER,
                detail="私钥格式无效，需要 PEM 格式"
            )
        
        # 加密私钥
        encrypted_key = crypto_service.encrypt_private_key(body.private_key_pem)
        
        # 计算 TTL 删除时间
        ttl_deletion_at = None
        if not cert.get("auto_renew"):
            from datetime import timedelta
            ttl_deletion_at = body.expires_at + timedelta(days=732)
        
        # 更新证书
        await db.certificates.update_one(
            {"_id": ObjectId(body.certificate_id)},
            {"$set": {
                "cert_fullchain_pem": body.cert_fullchain_pem,
                "key_encrypted": encrypted_key,
                "expires_at": body.expires_at,
                "issued_at": datetime.utcnow(),
                "ttl_deletion_at": ttl_deletion_at,
                "status": CertificateStatus.ISSUED.value,
                "updated_at": datetime.utcnow()
            }}
        )
        
        # 记录审计日志
        await log_audit(
            db, current_user["id"], AuditAction.CREATE,
            ResourceType.CERTIFICATE, AuditStatus.SUCCESS,
            request_id, resource_id=body.certificate_id,
            details={"action": "upload_certificate", "expires_at": body.expires_at.isoformat()}
        )
        
        return success(
            request, "UploadCertificate", SERVICE_NAME,
            UploadCertificateResult(
                certificate_id=body.certificate_id,
                status="issued",
                message="证书已成功上传"
            ).model_dump()
        )
        
    except Exception as e:
        return error(
            request, "UploadCertificate", SERVICE_NAME,
            ErrorCode.SYSTEM_ERROR,
            detail=str(e)
        )

